package IO流.综合练习;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class 网络爬虫 {
    public static void main(String[] args) throws IOException {

        //1.定义变量记录网址
        String familyNameNet="https://hanyu.baidu.com/s?wd=%E7%99%BE%E5%AE%B6%E5%A7%93&from=poem";
        String boyNameNet="http://www.haoming8.cn/baobao/10881.html";
        String girlNameNet="http://www.haoming8.cn/baobao/7641.html";

        //2.爬取数据
        String family = webCrawler(familyNameNet);
        String boy = webCrawler(boyNameNet);
        String girl = webCrawler(girlNameNet);

        //3.获取指定的数据-->并放到集合中
        ArrayList<String> familyDateTempList = getDate(family, "(.{4})([，。])", 1);
        ArrayList<String> boyDateTempList=getDate(boy,"([\\u4E00-\\u9FA5]{2})(、|。)",1);
        ArrayList<String> girlDateTempList=getDate(girl,"(.. ){4}..",0);

        //4.处理数据
       //处理姓氏，获取每一个姓氏
        //创建一个集合存储每一个姓氏
        ArrayList<String> familyList=new ArrayList<>();

        for (String s : familyDateTempList) {
            for (int i = 0; i < s.length(); i++) {
                char ch = s.charAt(i);
                familyList.add(String.valueOf(ch));
            }
        }
        System.out.println(familyList);

        //处理男孩的姓名--->有重复的姓名，进行去重
        ArrayList<String> boyList = boyDateTempList.stream().distinct().collect(Collectors.toCollection(ArrayList::new));
        System.out.println(boyList);

        //处理女生的姓名
        //创建一个集合储存女生的姓名
        ArrayList<String> girlList=new ArrayList<>();
        for (String s : girlDateTempList) {
            String[] split = s.split(" ");
            Collections.addAll(girlList,split);
        }
        System.out.println(girlList);

        //5.生成数据--->姓名-性别-年龄
        ArrayList<String> infos = getInfos(familyList, boyList, girlList, 5, 5);
        //打乱这个数组
        Collections.shuffle(infos);

        //6.把数据写入到文件中
        BufferedWriter bw=new BufferedWriter(new FileWriter("F\\name.txt"));
        for (String info : infos) {
            bw.write(info);
            bw.newLine();

        }
        //释放资源
        bw.close();
    }
    //定义一个从网上爬取数据的方法
    public static String webCrawler(String net) throws IOException {
        //1.创建一个URL对象
        URL url=new URL(net);
        //2.连接到网络
        URLConnection urlConnection = url.openConnection();
        //3.读取数据-->因为读取到的是字节，而网址中有中文，所以转化为字符
        InputStreamReader isr=new InputStreamReader(urlConnection.getInputStream());
        //4.创建一个StringBuilder对象进行数据的拼接-->因为获取到的是每一个字符
        StringBuilder sb=new StringBuilder();
        char[] chars=new char[1024*1024];
        int len;
        while ((len= isr.read(chars))!=-1) {
            sb.append(chars,0,len);
        }
        //5.释放资源
        isr.close();
        //6.返回读取到的数据
        return sb.toString();
    }

    //定义一个方法,根据正则表示,爬取想要的数据
    /*
        参数一:要匹配的文本
        参数二:正则表达式
        参数三:要匹配的正则表达式中的第几组数据
     */
    public static ArrayList<String> getDate(String str,String regex,int index){
        //创建存储数据的集合
        ArrayList<String> arr=new ArrayList<>();
        //1.获取正则表达式匹配器
        Pattern p=Pattern.compile(regex);
        //2.获取要匹配的文本对象
        Matcher m = p.matcher(str);
        //3.读取数据
        while (m.find()){
            arr.add(m.group(index));
        }
        return arr;
    }

    //定义一个方法生成男生的姓名和女生的姓名
    /*
    参数解释:
    familyList:存放姓的集合
    boyList:存放男生名字的集合
    girlList:存放女生姓名的集合;
    boyCount:生成的男生的个数;
    girlCount:生成女生的个数;
     */
    public static ArrayList<String> getInfos(ArrayList<String> familyList,
         ArrayList<String> boyList,ArrayList<String> girlList,int boyCount,int girlCount){
        Random ra=new Random();
        //1.生成男生的姓名;
        //创建一个Hashset集合存放男生的姓名
        HashSet<String> boyHs=new HashSet<>();
        while (boyHs.size()!=boyCount){
            //打乱姓和男生名子的集合
            Collections.shuffle(familyList);
            Collections.shuffle(boyList);
            //添加数据到HashSet集合中,年龄要求在18到27岁
            int boyAge = ra.nextInt(10) + 18;
            boyHs.add(familyList.get(0)+boyList.get(0)+"-男-"+boyAge);
        }
        //2.生成女生的姓名信息
        HashSet<String> girlHs=new HashSet<>();
        while (girlHs.size()!=girlCount){
            //打乱姓和女生姓名的集合
            Collections.shuffle(familyList);
            Collections.shuffle(girlList);
            //生成女生的年龄在18-25
            int girlAge = ra.nextInt(8) + 18;
            girlHs.add(familyList.get(0)+girlList.get(0)+"-女-"+girlAge);
        }
        //把姓名信息放进集合进行返回
        ArrayList<String> arr=new ArrayList<>(boyHs);
        arr.addAll(girlHs);
        return arr;
    }
}
